package ch11.optionDialog;

import java.awt.Component;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.geom.Rectangle2D;
import java.util.Date;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;

public class OptionDialogTest {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            var frame = new OptionDialogFrame();
            frame.setTitle("OptionDialogTest");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }
}

class OptionDialogFrame extends JFrame {
    private ButtonPanel typePanel;
    private ButtonPanel messagePanel;
    private ButtonPanel messageTypePanel;
    private ButtonPanel optionTypePanel;
    private ButtonPanel optionPanel;
    private ButtonPanel inputPanel;

    private String messageString = "Message";
    private Icon messageIcon = getIcon("blue-ball.gif");
    private Object messageObject = new Date();
    private Component messageComponent = new SampleComponent();

    public OptionDialogFrame() {
        var gridPanel = new JPanel();
        gridPanel.setLayout(new GridLayout(2, 3));

        // 对话框类型
        typePanel = new ButtonPanel("Type",
        "Message", "Confirm", "Option", "Input");

        // 根据选择 通过反射消息类型
        // 各种对话框 都有效
        messageTypePanel = new ButtonPanel("Message Type",
            "ERROR_MESSAGE", "INFORMATION_MESSAGE", "WARNING_MESSAGE",
            "QUESTION_MESSAGE", "PLAIN_MESSAGE");

        // 根据选择 获取消息对象（文本，图标，组件，对象数组，其他）
        // 各种对话框 都有效
        messagePanel = new ButtonPanel("Message",
            "String", "Icon", "Component", "Other", "Object[]");

        // 根据选择 通过反射获取选项类型
        // 确认对话框 和 选项对话框 才有效
        optionTypePanel = new ButtonPanel("Confirm",
            "DEFAULT_OPTION", "YES_NO_OPTION", "YES_NO_CANCEL_OPTION",
            "OK_CANCEL_OPTION");

        // 根据选择 获取选项对话框的选项数组
        // 选项对话框 才有效
        optionPanel = new ButtonPanel("Option",
            "String[]", "Icon[]", "Object[]");

        // 输入类型，有文本输入和组合框输入
        // 输入对话框 才有效
        inputPanel = new ButtonPanel("Input",
            "Text field", "Combo box");

        gridPanel.add(typePanel);
        gridPanel.add(messageTypePanel);
        gridPanel.add(messagePanel);
        gridPanel.add(optionTypePanel);
        gridPanel.add(optionPanel);
        gridPanel.add(inputPanel);

        var showPanel = new JPanel();
        var showButton = new JButton("Show");
        showButton.addActionListener(_ -> showDialog());
        showPanel.add(showButton);

        add(gridPanel, BorderLayout.CENTER);
        add(showPanel, BorderLayout.SOUTH);
        pack();
    }

    // 获取图标
    private Icon getIcon(String name) {
        var url = OptionDialogFrame.class.getResource(name);
        return url == null ? null : new ImageIcon(url);
    }

    // 消息对象
    public Object getMessage() {
        var s = messagePanel.getSelection();
        if (s.equals("String")) {
            return messageString;
        }
        if (s.equals("Icon")) {
            return messageIcon;
        }
        if (s.equals("Component")) {
            return messageComponent;
        }
        if (s.equals("Object[]")) {
            return new Object[] { messageString, messageIcon,
                messageComponent, messageObject };
        }
        if (s.equals("Other")) {
            return messageObject;
        }
        return null;
    }

    // 选项数组
    public Object[] getOptions() {
        var s = optionPanel.getSelection();
        if (s.equals("String[]")) {
            return new String[] { "Yellow", "Blue", "Red" };
        }
        if (s.equals("Icon[]")) {
            return new Icon[] { getIcon("blue-ball.gif"), getIcon("yellow-ball.gif"), getIcon("red-ball.gif") };
        }
        if (s.equals("Object[]")) {
            return new Object[] { messageString, messageIcon,
                messageComponent, messageObject };
        }
        return null;
    }

    // 通过反射获取 消息类型 和 选项类型
    public int getType(ButtonPanel panel) {
        var s = panel.getSelection();
        try {
            return JOptionPane.class.getField(s).getInt(null);
        } catch (Exception e) {
            return -1;
        }
    }

    private void showDialog() {
        // 消息对话框
        if (typePanel.getSelection().equals("Message")) {
            // 父组件，消息，标题，消息类型
            JOptionPane.showMessageDialog(
                OptionDialogFrame.this, getMessage(), "Title",
                getType(messageTypePanel));
        }
        // 确定对话框
        else if (typePanel.getSelection().equals("Confirm")) {
            // 父组件，消息，标题，选项类型，消息类型
            JOptionPane.showConfirmDialog(
                OptionDialogFrame.this, getMessage(), "Title",
                getType(optionTypePanel), getType(messageTypePanel));
        }
        // 选项对话框
        else if (typePanel.getSelection().equals("Option")) {
            // 父组件，消息，标题，选项类型，消息类型，选项数组，默认选项
            JOptionPane.showOptionDialog(
                OptionDialogFrame.this, getMessage(), "Title",
                getType(optionTypePanel), getType(messageTypePanel),
                null, getOptions(), getOptions()[0]);
        }
        // 输入对话框
        else if (typePanel.getSelection().equals("Input")) {
            // 文本输入
            if (inputPanel.getSelection().equals("Text field")) {
                // 父组件，消息，标题，消息类型
                JOptionPane.showInputDialog(
                    OptionDialogFrame.this, getMessage(), "Title",
                    getType(messageTypePanel));
            }
            // 组合框输入
            else {
                // 父组件，消息，标题，消息类型，默认选项，选项数组，初始选择
                JOptionPane.showInputDialog(
                    OptionDialogFrame.this, getMessage(), "Title",
                    getType(messageTypePanel), null,
                    new String[] { "Yellow", "Blue", "Red" },
                    "Blue");
            }
        }
    }
}

class SampleComponent extends JComponent {
    @Override
    public void paintComponent(Graphics g) {
        var g2 = (Graphics2D) g;
        var rect = new Rectangle2D.Double(0, 0, getWidth() - 1, getHeight() - 1);
        g2.setPaint(Color.YELLOW);
        g2.fill(rect);
        g2.setPaint(Color.BLUE);
        g2.draw(rect);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(10, 10);
    }
}

class ButtonPanel extends JPanel {
   private ButtonGroup group;

   public ButtonPanel(String title, String... options) {
       setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), title));
       setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
       group = new ButtonGroup();

       for (String option : options) {
           var button = new JRadioButton(option);
           button.setActionCommand(option);
           add(button);
           group.add(button);
           // 默认选中第一个
           button.setSelected(option == options[0]);
       }
   }

   public String getSelection() {
       return group.getSelection().getActionCommand();
   }
}